#include "Allocator.h"
#include <cassert>


StackAllocator::StackAllocator(std::size_t n)
	: begin_(new unsigned char[n]), end_(begin_ + n), current_(begin_)
#ifdef	DEBUG_ALLOCATOR
	,maxAllocatedSize_()
#endif
{
#ifdef DEBUG_ALLOCATOR
	std::clog << "initial stack: current = " << (void*)current_ << " / size = " << size() << '\n';
#endif
}
StackAllocator::~StackAllocator()
{
	assert(current_ == begin_);
	delete [] begin_;
#ifdef DEBUG_ALLOCATOR
	std::clog << "max allocated size: " << maxAllocatedSize_ << '\n';
#endif
}


void* StackAllocator::allocate(std::size_t n)
{
	const std::size_t requiredSize = n;
	if (requiredSize > freeSize())
		throw std::bad_alloc();
	void* retval = current_;
	current_ += n;
#ifdef DEBUG_ALLOCATOR
	if (maxAllocatedSize_ < size())	maxAllocatedSize_ = size();
	std::clog << "stack allocated: retval = " << retval 
	          << " / current = " << (void*)current_ << '\n';
#endif
	return retval;
}

void StackAllocator::deallocate(void* p)
{
	if (p)
	{
		current_= reinterpret_cast<unsigned char*>(p);
#ifdef DEBUG_ALLOCATOR
	std::clog << "stack deallocated: current = " << (void*)current_ << '\n';
#endif
	}
}